/*
 * Classe StatOne
 *                          - Obtem os dados da estatística 1 da base de dados (SQLite3 + ADO.NET) 
 * 							- Guarda esses dados numa Lista (C# Collections)
 * 							- Ordena os dados
 * 							- Escreve os resultados na consola e no ficheiro de texto respectivo
 *
 *@Author: Fábio Miguel Vitória Carreto - 5618 - Engenharia Informática - Diurno
 *@Version: 03/07/2011
 * 
 * 
 * */

using System;
using System.Collections.Generic;
using System.Data;
using Mono.Data.SqliteClient;
using System.IO;

public class StatOne
{
	
	public StatOne ()
	{
		//Obtem os dados para uma lista
		List<StructOne> statOne = this.getData();
		//Ordena a lista
		List<StructOne> statOrdenada = this.mostraListaOrdenada(statOne);
		//Mostra resultados na consola
		this.showResultsConsole(statOrdenada);
		//Guarda resultados no ficheiro de texto
		this.showResultsFile(statOrdenada);
	}
	
	
	//Método que recebe a lista desordenada e devolve uma do mesmo tipo mas ordenada
	//pela contagem, utilizando o Sort do C#
	public List<StructOne> mostraListaOrdenada(List<StructOne> stat)
	{
		stat.Sort(delegate(StructOne s1, StructOne s2) { return s1.count.CompareTo(s2.count); });
		
		return stat;
	}
	
	//Método que mostra a lista com os resultados na consola
	public void showResultsConsole(List<StructOne> stat)
	{
		
		Console.WriteLine("\nResultados (Ordenados pela Contagem Crescente):\n");
		//Mostra o ano e o total respectivo obtido para a estatística
		stat.ForEach(delegate(StructOne s) 
		{ 
			Console.WriteLine(String.Format("Ano = 200{0}, Número = {1}", s.year, s.count)); 
		});
		
	}
	
	//Método que mostra os resultados da lista num ficheiro de texto
	public void showResultsFile(List<StructOne> stat)
	{
		
		//Nome do ficheiro
		string file = "Estatísticas/statOne.txt";
		//Cabeçalho do ficheiro com a data, hora, sistema operativo e título da estatística
		TextWriter tw = new StreamWriter(file);
		tw.WriteLine(DateTime.Now);
		tw.WriteLine("Sistema Operativo: " + Environment.OSVersion.ToString());
		tw.WriteLine("");
		tw.WriteLine("Estatística 1 - Número de Docentes por ano no Ensino Superior" + Environment.NewLine);
		tw.WriteLine("(Resultados ordenados pela contagem crescente)");
		tw.Close();
		
		//Adiciona ao ficheiro o conteúdo da lista adaptando o formato
		stat.ForEach(delegate(StructOne s) 
		{
			File.AppendAllText(file, String.Format("Ano = 200{0}, Número = {1}" + Environment.NewLine, s.year, s.count));
		});
		
		//Mostra ao utilizador onde pode encontrar o ficheiro respectivo
		Console.WriteLine("\nOs resultados da estatística 1 foram também guardados em ficheiro de texto.");
		Console.WriteLine("Localização: " + file);
		
	}
	
	//Método que obtém os dados necessários utilizando o SQLite e ADODB.NET
	public List<StructOne> getData()
	{
		//Conexão à base de dados e definição do reader que irá conter
		//os dados obtidos
		string connectionString = "URI=file:rebides.db,version=3";
		IDbConnection dbcon;
		dbcon = (IDbConnection) new SqliteConnection(connectionString);
		dbcon.Open();
		IDbCommand dbcmd = dbcon.CreateCommand();
		IDataReader reader = null;
		
		//Lista de objectos StructOne com resultados a devolver
		List<StructOne> stat = new List<StructOne>();
		
		//Para cada ano obtém os dados pretendidos
		for(int ano = 0; ano < 10 ; ano++)
		{

			//Obterá o total de docentes em cada ano registados na tabela registodocencia
			string sql = "SELECT COUNT(DISTINCT docente_id) FROM registodocencia WHERE ano = " + ano;
			dbcmd.CommandText = sql;
			reader = dbcmd.ExecuteReader();
			
			//Obtém os dados do reader guarda cada linha obtida (com a contagem)
			//na lista de objectos, em conjunto com o ano a que corresponde essa contagem
			while(reader.Read()) 
			{
				string numero = reader.GetString (0);
				stat.Add(new StructOne(ano, numero));
			}
		}
		
		return stat;
		
	}
}

//Objecto que servirá de base à estatística
//Terá como atributos o ano e a respectiva contagem de docentes
public class StructOne
{
	public int year;
	public string count;
	
	public StructOne(int year, string count)
	{
		this.year = year;
		this.count = count;
	}
}
